import 'dart:io';

import 'package:downloadsfolder/downloadsfolder.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path/path.dart' as p;

import '../logger.dart';

enum FileType { ts, m3u8, key, notknown }

abstract class M3u8Utils {
  static FileType fileType(String url) {
    final suffix = p.extension(url);
    if (suffix.startsWith('.ts')) {
      return FileType.ts;
    }
    if (suffix.startsWith('.m3u8') || suffix.startsWith('.m3u')) {
      return FileType.m3u8;
    }
    if (suffix.startsWith('.key')) return FileType.key;
    return FileType.notknown;
  }

  static Uri? toFullUri(String resourceRawUrl, Uri m3u8Uri) {
    if (resourceRawUrl.startsWith('http')) {
      return Uri.tryParse(resourceRawUrl);
    } else if (resourceRawUrl.startsWith('/')) {
      return Uri(
        scheme: m3u8Uri.scheme,
        userInfo: m3u8Uri.userInfo,
        host: m3u8Uri.host,
        port: m3u8Uri.port,
        path: resourceRawUrl,
      );
    } else {
      final pathSegments = [...m3u8Uri.pathSegments];
      if (pathSegments.isNotEmpty) {
        pathSegments.removeLast();
      }
      pathSegments.add(resourceRawUrl);
      return Uri(
        scheme: m3u8Uri.scheme,
        userInfo: m3u8Uri.userInfo,
        host: m3u8Uri.host,
        port: m3u8Uri.port,
        pathSegments: pathSegments,
      );
    }
  }

  static Future<bool> deleteFile(String tempfile) async {
    try {
      File file = File(tempfile);
      await file.delete();
      return true;
    } catch (e) {
      return false;
    }
  }

  static Future<bool> renameFile(String from, String to) async {
    try {
      File file = File(from);
      await file.rename(to);
      return true;
    } catch (e) {
      return false;
    }
  }

  static Future<bool> writeStringToFile(String toFile, String contents) async {
    try {
      File file = File(toFile);
      await file.writeAsString(contents);
      return true;
    } catch (e) {
      return false;
    }
  }

  static Future<bool?> fileExists(String filePath) async {
    try {
      final file = File(filePath);
      return file.exists();
    } catch (e) {
      return null;
    }
  }

  static Future<int?> fileLength(String filePath) async {
    try {
      final file = File(filePath);
      return file.length();
    } catch (e) {
      return null;
    }
  }

  static Future<bool> ensureDir(String dirPath) async {
    try {
      final directory = Directory(dirPath);
      if (!await directory.exists()) {
        await directory.create(recursive: true);
      }
      return true;
    } catch (e) {
      return false;
    }
  }

  static Future<String?> readFileAsString(String path) async {
    try {
      final file = File(path);
      return await file.readAsString();
    } catch (e) {
      return null;
    }
  }

  static Future<bool> moveToGalleryOrDownloads(String tempfile) async {
    if (Platform.isAndroid) {
      try {
        final downloads = await getDownloadDirectory();
        File file = File(tempfile);
        final basename = p.basename(tempfile);
        final newFile = await file.rename('${downloads.path}/$basename');
        logger
            .d('move to Downloads filepath:$tempfile success:${newFile.path}');
        return true;
      } catch (e) {
        logger.d('move to Downloads filepath:$tempfile exception$e');
        return false;
      }
    } else if (Platform.isIOS) {
      try {
        final basename = p.basename(tempfile);
        final result =
            await ImageGallerySaver.saveFile(tempfile, name: basename);
        final ok = result["isSuccess"];
        if (ok) {
          deleteFile(tempfile);
        }
        logger.d('move to Gallery filepath$tempfile, ok:$ok');
        return ok;
      } catch (e) {
        logger.d('move to Gallery filepath$tempfile, exception:$e');
        return false;
      }
    } else {
      logger.d('moveFromTempDir not supported ${Platform.operatingSystem}');
      return false;
    }
  }
}
